package com.scut.online_black_market.log;

import com.alibaba.fastjson.JSON;
import com.sun.corba.se.spi.ior.ObjectKey;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

/**
 * create by yellowBroke on 2020年10月21日 09点52分
 * 使用AOP 切面打印日志
 */

@Aspect
@Component
@Slf4j
public class RequestLogAspect {

    // 定义切入点，在接收到请求时处理
    @Pointcut("execution(public * com.scut.online_black_market.controller..*(..))")
    public void controller(){};

    @Before("controller()")
    public void doBefore(JoinPoint joinPoint) {
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();

        if (servletRequestAttributes != null) {

            HttpServletRequest request =servletRequestAttributes.getRequest();

            log.info("---------------------------------------------------------------------------------------");
            log.info("IP                 : {}", request.getRemoteAddr());
            log.info("URL                : {}", request.getRequestURL().toString());
            log.info("HTTP Method        : {}", request.getMethod());
            log.info("Class Method       : {}.{}", joinPoint.getSignature().getDeclaringTypeName(),
                    joinPoint.getSignature().getName());
            log.info("Token.             : {}",request.getHeader("Authorization"));
        }
    }

    @Around("controller()")
    public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        long start = System.currentTimeMillis();
        Object result = proceedingJoinPoint.proceed();
        log.info("Request Params     : {}", getRequestParams(proceedingJoinPoint));
        log.info("Result             : {}", JSON.toJSON(result));
        log.info("Time Cost          : {} ms", System.currentTimeMillis() - start);
        log.info("------------------------------------------------------------------------");
        return result;
    }

    @After("controller()")
    public void doAfter() {
        log.info("------------------------------------------------------------------------");
    }

    /**
     * 获取传入参数
     *
     * @param proceedingJoinPoint
     * @return Hash Map requestParams
     */
    private Map<String, Object> getRequestParams(ProceedingJoinPoint proceedingJoinPoint) {

        Map<String, Object> requestParam = new HashMap<>();

        String[] paramNames = ( (MethodSignature) proceedingJoinPoint.getSignature()).getParameterNames();


        Object[] args = proceedingJoinPoint.getArgs();

        for (int i = 0; i < paramNames.length; i++) {
            Object value = args[i];

            if (value instanceof MultipartFile) {
                value = ((MultipartFile) value).getOriginalFilename();
            }

            requestParam.put(paramNames[i], value);
        }

        return requestParam;
    }
}

